﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace OrBitDataModule.ScripterDebugger
{
    internal static class ProcessHelper
    {
        /// <summary>
        /// 运行exe返回ProcessId
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="arguments"></param>
        /// <returns></returns>

        public static int RunProcess(string fileName, string arguments)
        {
            ProcessStartInfo startInfo = new ProcessStartInfo(fileName, arguments);
            startInfo.UseShellExecute = false;
            startInfo.RedirectStandardOutput = true;
            startInfo.RedirectStandardError = true;
            startInfo.CreateNoWindow = true;
   
            using (Process process = Process.Start(startInfo))
            {
                Thread.Sleep(3000);
                // 等待进程主窗口句柄出现
                //int i = 0;
                //while (process.MainWindowHandle == IntPtr.Zero && i < 1000)
                //{
                //    Thread.Sleep(100);
                //    i++;
                //}
                return process.Id;
            }
        }

        public static void TerminateProcessesByFilePath(string targetFilePath)
        {
            Process[] allProcesses = Process.GetProcesses();
            foreach (Process process in allProcesses)
            {
                IntPtr handle = IntPtr.Zero;

                try
                {
                    // 尝试获取进程的主模块路径
                    handle = OpenProcess(ProcessAccessFlags.QueryInformation | ProcessAccessFlags.VirtualMemoryRead, false, process.Id);
                    if (handle == IntPtr.Zero)
                        continue;

                    string processPath = process.MainModule?.FileName;
                    if (!string.IsNullOrWhiteSpace(processPath) && processPath.Equals(targetFilePath, StringComparison.OrdinalIgnoreCase))
                    {
                        process.Kill();
                        return;
                    }
                }
                catch
                {
                    // 忽略异常
                }
                finally
                {
                    if (handle != IntPtr.Zero)
                    {
                        CloseHandle(handle);
                    }
                }
            }
        }

        [Flags]
        public enum ProcessAccessFlags : uint
        {
            QueryInformation = 0x400,
            VirtualMemoryRead = 0x10
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(IntPtr hObject);

        public static void TerminateProcessesByProcessId(int processId)
        {
            try
            {
                Process targetProcess = Process.GetProcessById(processId);

                if (targetProcess != null && !targetProcess.HasExited)
                {
                    targetProcess.Kill();
                }
            }
            catch { }
        }
    }
}
